local Vector = require('lib.brinevector')
local Timer = require('lib.hump.timer')

local Utype = require('src.gen.utype')
local UState = require('src.gen.ustate')
local PhState = require('src.gen.physics_state')
local DState = require('src.gen.draw_state')
local Path = require('src.gen.path')
local Weapon = require('src.gen.weapon')

local BUA = require "AI.gen.basic_unit"

return Class{
   _name = "Unit",

   select = function (self)
      lume.each(Game.upool.pool, function (v) v.selected = nil end)
      self.selected = true
   end,
   
   focus = function (self)
      Game.current_screen:center_view(self.x, self.y)
   end,

   is_hovered = function (self)
      local cursor = Game.cursor
      local cx, cy = cursor:get_position()
      return cx == self.x and cy == self.y
   end,
   
   activate = function (self)
      self.inactive = false
      self._ai:start(self)
--      self._unit_state:start(self)
      self._physics_state:start(self)
      self._draw_state:start(self)
      if self.timer then self.timer:clear() else self.timer = Timer.new() end
   end,

   desactivate = function (self)
      self.inactive = true
   end,

   get_position = function (self)
      return self.x, self.y
   end,
   
   init = function (self, name, x, y, friendly)
      self.friendly = friendly or true
      self.inactive = true
      self.name, self.x, self.y = name, x or 0, y or 0
      local data, utype = Game:get_unit (name)
      --print(utype)
      self.utype = Utype(utype)
      self.move_type = self:_get_info_chunk (data[2])
      if self.move_type == "tr" then --tracted
	 _, self.vehicle = self:_get_info_chunk (data[2])
      elseif self.move_type == "sp" then --self-propelled
	 _, self.speed_on_road, self.speed_off_road = self:_get_info_chunk (data[2])
      end
      self.primary_weapon = Weapon(self:_get_info_chunk (data[3]))
      self.secondary_weapon = Weapon(self:_get_info_chunk (data[4]))
      self.cost = self:_get_info_chunk(data[5])

      self._path_handler = Path()
      self._ai = BUA()
      self._draw_state = DState()
      self._physics_state = PhState()
      return self
   end,
   
   draw = function (self)
      self._draw_state:draw()
   end,

   __to_string = function (self)
      return string.format([[
			Name: %s
			Movement: %s
			Weapons:
				- %s
				- %s
		]], self.name,
		self.move_type,
		self.primary_weapon:get_info(),
		self.secondary_weapon:get_info())
   end,
   
   _get_info_chunk = function (self, s)
      return table.unpack(pl.stringx.split(s, ":"))
   end,

   spawn = function (self, x, y)
      Game.upool:add(self)
      return self
   end,

   destroy = function (self)
      lume.remove(Game.upool.pool, self)
   end,

   update = function (self, dt)
      self.timer:update(dt)
      self._ai:update(dt)
      --self._unit_state:update(dt)
      self._physics_state:update(dt)
      self._draw_state:update(dt)
      
   end,

   is_moving = function (self)
      return not ((self:get_velocity_length() == 0))
   end,

   try_move = function (self, x, y)
      if not self:is_moving() then
	 self:request_path(x, y)
      end
   end,

   request_path = function (self, x, y)
      self.path = self._path_handler:get_path_to(self.x, self.y, x, y)
   end,

   get_next_path_point = function (self)
      return self._path_handler:get_next_point()
   end,

   start_movement = function (self)
      self.objective = self:get_next_path_point()
      if self.objective then
	 --pl.pretty.dump(self.objective)
	 self._physics_state:move(self.objective.x*8, self.objective.y*8)
      end
   end,

   get_velocity_length = function (self)
      return self._physics_state:get_velocity_length()
   end
}
